<template>
  <div class="datasource-container">
    <el-card shadow="never">
      <template #header>
        <div class="card-header">
          <span>数据源管理</span>
          <el-button type="primary" @click="handleAdd">
            <el-icon><Plus /></el-icon>
            新增数据源
          </el-button>
        </div>
      </template>

      <!-- 搜索区域 -->
      <div class="search-box">
        <el-form :inline="true" :model="searchForm">
          <el-form-item label="数据源名称">
            <el-input 
              v-model="searchForm.name" 
              placeholder="请输入数据源名称"
              clearable
              @clear="handleSearch"
            />
          </el-form-item>
          <el-form-item label="数据库类型">
            <el-select 
              v-model="searchForm.dbType" 
              placeholder="请选择数据库类型"
              clearable
              @clear="handleSearch"
            >
              <el-option label="全部" value="" />
              <el-option 
                v-for="type in dbTypes" 
                :key="type.value" 
                :label="type.label" 
                :value="type.value" 
              />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="handleSearch">
              <el-icon><Search /></el-icon>
              查询
            </el-button>
            <el-button @click="handleReset">
              <el-icon><Refresh /></el-icon>
              重置
            </el-button>
          </el-form-item>
        </el-form>
      </div>

      <!-- 表格区域 -->
      <el-table 
        :data="tableData" 
        border 
        stripe
        v-loading="loading"
        style="width: 100%"
      >
        <el-table-column type="index" label="序号" width="60" align="center" />
        <el-table-column prop="name" label="数据源名称" min-width="150" />
        <el-table-column prop="dbType" label="数据库类型" width="120" align="center">
          <template #default="{ row }">
            <el-tag :type="getDbTypeTagColor(row.dbType)">
              {{ getDbTypeName(row.dbType) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="host" label="主机地址" min-width="150" />
        <el-table-column prop="port" label="端口" width="80" align="center" />
        <el-table-column prop="database" label="数据库名" min-width="120" />
        <el-table-column prop="username" label="用户名" width="120" />
        <el-table-column prop="status" label="状态" width="100" align="center">
          <template #default="{ row }">
            <el-tag :type="row.status === 1 ? 'success' : 'danger'">
              {{ row.status === 1 ? '启用' : '禁用' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="创建时间" width="180" />
        <el-table-column label="操作" width="280" align="center" fixed="right">
          <template #default="{ row }">
            <el-button 
              type="primary" 
              size="small" 
              link
              @click="handleTest(row)"
            >
              <el-icon><Connection /></el-icon>
              测试连接
            </el-button>
            <el-button 
              type="primary" 
              size="small" 
              link
              @click="handleEdit(row)"
            >
              <el-icon><Edit /></el-icon>
              编辑
            </el-button>
            <el-button 
              type="danger" 
              size="small" 
              link
              @click="handleDelete(row)"
            >
              <el-icon><Delete /></el-icon>
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div class="pagination">
        <el-pagination
          v-model:current-page="pagination.page"
          v-model:page-size="pagination.size"
          :page-sizes="[10, 20, 50, 100]"
          :total="pagination.total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </el-card>

    <!-- 新增/编辑弹窗 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogTitle"
      width="800px"
      :close-on-click-modal="false"
      @close="handleDialogClose"
    >
      <el-form 
        ref="formRef" 
        :model="form" 
        :rules="rules" 
        label-width="120px"
      >
        <el-form-item label="数据源名称" prop="name">
          <el-input 
            v-model="form.name" 
            placeholder="请输入数据源名称"
            clearable
          />
        </el-form-item>
        <el-form-item label="数据库类型" prop="dbType">
          <el-select 
            v-model="form.dbType" 
            placeholder="请选择数据库类型"
            @change="handleDbTypeChange"
            style="width: 100%"
          >
            <el-option 
              v-for="type in dbTypes" 
              :key="type.value" 
              :label="type.label" 
              :value="type.value"
            >
              <span style="float: left">{{ type.label }}</span>
              <span style="float: right; color: var(--el-text-color-secondary); font-size: 13px">
                {{ type.desc }}
              </span>
            </el-option>
          </el-select>
        </el-form-item>
        <el-row :gutter="20">
          <el-col :span="16">
            <el-form-item label="主机地址" prop="host">
              <el-input 
                v-model="form.host" 
                placeholder="请输入主机地址"
                clearable
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="端口" prop="port">
              <el-input-number 
                v-model="form.port" 
                :min="1" 
                :max="65535"
                controls-position="right"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="数据库名" prop="database">
          <el-input 
            v-model="form.database" 
            placeholder="请输入数据库名"
            clearable
          />
        </el-form-item>
        <el-form-item label="用户名" prop="username">
          <el-input 
            v-model="form.username" 
            placeholder="请输入用户名"
            clearable
          />
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input 
            v-model="form.password" 
            type="password"
            placeholder="请输入密码"
            show-password
            clearable
          />
        </el-form-item>
        
        <!-- 高级配置 -->
        <el-divider>高级配置</el-divider>
        
        <el-form-item label="字符编码">
          <el-select 
            v-model="form.charset" 
            placeholder="请选择字符编码"
            style="width: 100%"
          >
            <el-option label="UTF-8" value="utf8" />
            <el-option label="UTF-8MB4" value="utf8mb4" />
            <el-option label="GBK" value="gbk" />
            <el-option label="GB2312" value="gb2312" />
          </el-select>
        </el-form-item>
        
        <el-form-item label="连接参数">
          <el-input 
            v-model="form.params" 
            type="textarea"
            :rows="3"
            placeholder="请输入额外的连接参数，如：useSSL=false&serverTimezone=Asia/Shanghai"
            clearable
          />
        </el-form-item>

        <el-form-item label="JDBC URL" prop="jdbcUrl">
          <el-input 
            v-model="jdbcUrl" 
            type="textarea"
            :rows="3"
            readonly
            placeholder="自动生成的JDBC连接字符串"
          >
            <template #append>
              <el-button @click="copyJdbcUrl">
                <el-icon><DocumentCopy /></el-icon>
                复制
              </el-button>
            </template>
          </el-input>
        </el-form-item>

        <el-form-item label="状态">
          <el-switch 
            v-model="form.status" 
            :active-value="1" 
            :inactive-value="0"
            active-text="启用"
            inactive-text="禁用"
          />
        </el-form-item>

        <el-form-item label="描述">
          <el-input 
            v-model="form.description" 
            type="textarea"
            :rows="3"
            placeholder="请输入数据源描述"
            maxlength="200"
            show-word-limit
          />
        </el-form-item>
      </el-form>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSubmit" :loading="submitLoading">
            确定
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { 
  Plus, Search, Refresh, Edit, Delete, Connection, DocumentCopy 
} from '@element-plus/icons-vue'
import { 
  getDataSourceList, 
  addDataSource, 
  updateDataSource, 
  deleteDataSource,
  testConnection
} from '@/api/datasource'
import { generateJdbcUrl } from '@/utils/jdbcUrlGenerator'

// 数据库类型配置
const dbTypes = [
  { value: 'mysql', label: 'MySQL', desc: 'MySQL 5.x/8.x', defaultPort: 3306, driver: 'com.mysql.cj.jdbc.Driver' },
  { value: 'postgresql', label: 'PostgreSQL', desc: 'PostgreSQL 9.x+', defaultPort: 5432, driver: 'org.postgresql.Driver' },
  { value: 'sqlserver', label: 'SQL Server', desc: 'SQL Server 2008+', defaultPort: 1433, driver: 'com.microsoft.sqlserver.jdbc.SQLServerDriver' },
  { value: 'oracle', label: 'Oracle', desc: 'Oracle 11g/12c/19c', defaultPort: 1521, driver: 'oracle.jdbc.driver.OracleDriver' },
  { value: 'dm', label: '达梦数据库', desc: 'DM 7.x/8.x', defaultPort: 5236, driver: 'dm.jdbc.driver.DmDriver' },
  { value: 'kingbase', label: '人大金仓', desc: 'KingbaseES V8', defaultPort: 54321, driver: 'com.kingbase8.Driver' },
  { value: 'gbase', label: '南大通用', desc: 'GBase 8s/8t', defaultPort: 5258, driver: 'com.gbase.jdbc.Driver' },
  { value: 'mariadb', label: 'MariaDB', desc: 'MariaDB 10.x', defaultPort: 3306, driver: 'org.mariadb.jdbc.Driver' },
  { value: 'db2', label: 'DB2', desc: 'IBM DB2 10.x+', defaultPort: 50000, driver: 'com.ibm.db2.jcc.DB2Driver' },
  { value: 'clickhouse', label: 'ClickHouse', desc: 'ClickHouse 20.x+', defaultPort: 8123, driver: 'ru.yandex.clickhouse.ClickHouseDriver' }
]

// 搜索表单
const searchForm = reactive({
  name: '',
  dbType: ''
})

// 表格数据
const tableData = ref([])
const loading = ref(false)

// 分页
const pagination = reactive({
  page: 1,
  size: 10,
  total: 0
})

// 对话框
const dialogVisible = ref(false)
const dialogTitle = ref('新增数据源')
const formRef = ref()
const submitLoading = ref(false)

// 表单数据
const form = reactive({
  id: null,
  name: '',
  dbType: '',
  host: '',
  port: 3306,
  database: '',
  username: '',
  password: '',
  charset: 'utf8mb4',
  params: '',
  status: 1,
  description: ''
})

// 动态生成的JDBC URL
const jdbcUrl = computed(() => {
  if (!form.dbType || !form.host || !form.database) {
    return ''
  }
  return generateJdbcUrl({
    dbType: form.dbType,
    host: form.host,
    port: form.port,
    database: form.database,
    charset: form.charset,
    params: form.params
  })
})

// 表单验证规则
const rules = {
  name: [
    { required: true, message: '请输入数据源名称', trigger: 'blur' }
  ],
  dbType: [
    { required: true, message: '请选择数据库类型', trigger: 'change' }
  ],
  host: [
    { required: true, message: '请输入主机地址', trigger: 'blur' }
  ],
  port: [
    { required: true, message: '请输入端口', trigger: 'blur' }
  ],
  database: [
    { required: true, message: '请输入数据库名', trigger: 'blur' }
  ],
  username: [
    { required: true, message: '请输入用户名', trigger: 'blur' }
  ],
  password: [
    { required: true, message: '请输入密码', trigger: 'blur' }
  ]
}

// 获取数据库类型标签颜色
const getDbTypeTagColor = (dbType) => {
  const colorMap = {
    mysql: 'primary',
    postgresql: 'success',
    sqlserver: 'warning',
    oracle: 'danger',
    dm: 'info',
    kingbase: '',
    gbase: 'success',
    mariadb: 'primary',
    db2: 'warning',
    clickhouse: 'danger'
  }
  return colorMap[dbType] || ''
}

// 获取数据库类型名称
const getDbTypeName = (dbType) => {
  const type = dbTypes.find(t => t.value === dbType)
  return type ? type.label : dbType
}

// 数据库类型变化
const handleDbTypeChange = (value) => {
  const type = dbTypes.find(t => t.value === value)
  if (type) {
    form.port = type.defaultPort
  }
}

// 查询
const handleSearch = () => {
  pagination.page = 1
  loadData()
}

// 重置
const handleReset = () => {
  searchForm.name = ''
  searchForm.dbType = ''
  handleSearch()
}

// 新增
const handleAdd = () => {
  dialogTitle.value = '新增数据源'
  dialogVisible.value = true
}

// 编辑
const handleEdit = (row) => {
  dialogTitle.value = '编辑数据源'
  Object.assign(form, { ...row })
  dialogVisible.value = true
}

// 删除
const handleDelete = (row) => {
  ElMessageBox.confirm(
    `确定要删除数据源"${row.name}"吗？`,
    '提示',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }
  ).then(async () => {
    try {
      await deleteDataSource(row.id)
      ElMessage.success('删除成功')
      loadData()
    } catch (error) {
      ElMessage.error('删除失败：' + error.message)
    }
  }).catch(() => {
    // 取消删除
  })
}

// 测试连接
const handleTest = async (row) => {
  const loading = ElMessage({
    message: '正在测试连接...',
    duration: 0,
    type: 'info'
  })
  try {
    await testConnection(row.id)
    loading.close()
    ElMessage.success('连接成功！')
  } catch (error) {
    loading.close()
    ElMessage.error('连接失败：' + error.message)
  }
}

// 提交
const handleSubmit = async () => {
  if (!formRef.value) return
  
  await formRef.value.validate(async (valid) => {
    if (valid) {
      submitLoading.value = true
      try {
        if (form.id) {
          await updateDataSource(form.id, form)
          ElMessage.success('更新成功')
        } else {
          await addDataSource(form)
          ElMessage.success('新增成功')
        }
        dialogVisible.value = false
        loadData()
      } catch (error) {
        ElMessage.error('操作失败：' + error.message)
      } finally {
        submitLoading.value = false
      }
    }
  })
}

// 复制JDBC URL
const copyJdbcUrl = () => {
  if (!jdbcUrl.value) {
    ElMessage.warning('请先完善数据源配置')
    return
  }
  navigator.clipboard.writeText(jdbcUrl.value).then(() => {
    ElMessage.success('已复制到剪贴板')
  }).catch(() => {
    ElMessage.error('复制失败')
  })
}

// 对话框关闭
const handleDialogClose = () => {
  formRef.value?.resetFields()
  form.id = null
  form.name = ''
  form.dbType = ''
  form.host = ''
  form.port = 3306
  form.database = ''
  form.username = ''
  form.password = ''
  form.charset = 'utf8mb4'
  form.params = ''
  form.status = 1
  form.description = ''
}

// 分页改变
const handleSizeChange = (size) => {
  pagination.size = size
  loadData()
}

const handleCurrentChange = (page) => {
  pagination.page = page
  loadData()
}

// 加载数据
const loadData = async () => {
  loading.value = true
  try {
    const params = {
      page: pagination.page,
      size: pagination.size,
      name: searchForm.name,
      dbType: searchForm.dbType
    }
    const res = await getDataSourceList(params)
    tableData.value = res.data.list
    pagination.total = res.data.total
  } catch (error) {
    ElMessage.error('加载数据失败：' + error.message)
  } finally {
    loading.value = false
  }
}

onMounted(() => {
  loadData()
})
</script>

<style scoped>
.datasource-container {
  padding: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.search-box {
  margin-bottom: 20px;
}

.pagination {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
</style>

